package cn.mw.cmdb.virtualization.strategy.handler.query;

import cn.mw.cmdb.param.MwCoordinateDataInfo;
import cn.mw.cmdb.param.MwItemHistoryResult;
import cn.mw.cmdb.util.BaseUtil;
import cn.mw.cmdb.virtualization.dto.HistoryOrTrendDto;
import cn.mw.cmdb.virtualization.dto.VirtualizationBaseDto;
import cn.mw.cmdb.virtualization.enums.VirtualizationDataTypeEnum;
import cn.mw.cmdb.virtualization.param.VirtualizationParam;
import cn.mw.cmdb.virtualization.service.ZabbixMonitorHandler;
import cn.mw.cmdb.virtualization.service.handler.ZabbixHistoryHandler;
import cn.mw.cmdb.virtualization.service.handler.ZabbixTrendHandler;
import cn.mw.cmdb.virtualization.strategy.handler.VirtualizationTypeHandler;
import cn.mw.main.api.common.ZabbixDubboService;
import cn.mw.microMonitorCommon.entity.UnitResult;
import cn.mw.microMonitorCommon.util.UnitUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @description 虚拟化主机类型
 */
@Service
@Slf4j
public class VirtualizationHistoryHandler implements VirtualizationTypeHandler {

    private final Integer groupCount = 100;

    @DubboReference(check = false, timeout = 120000)
    private ZabbixDubboService zabbixDubboService;

    @Override
    public List<String> getType() {
        return Arrays.asList(VirtualizationDataTypeEnum.HISTORY.getDataType(), VirtualizationDataTypeEnum.TREND.getDataType());
    }

    @Override
    public Object getTypeData(List<VirtualizationBaseDto> baseDtos, VirtualizationParam param, Integer serverId) {
        List<MwItemHistoryResult> historyResultList = new ArrayList<>();
        //获取hostID集合
        List<String> hostIds = baseDtos.stream().filter(item -> StringUtils.isNotEmpty(item.getHostId())).map(s -> s.getHostId()).collect(Collectors.toList());
        VirtualizationDataTypeEnum dataTypeEnum = VirtualizationDataTypeEnum.getDataTypeEnum(param.getQueryType());
        List<Long> times = BaseUtil.getTimeIntervalByType(param.getStartTime(), param.getEndTime(), param.getDateType());
        ZabbixMonitorHandler handler = null;
        switch (dataTypeEnum){
            case HISTORY:
                handler = new ZabbixHistoryHandler(zabbixDubboService, param.getServerId(), param.getItemNames(), hostIds, times.get(0), times.get(1));
                break;
            case TREND:
                handler = new ZabbixTrendHandler(zabbixDubboService, param.getServerId(), param.getItemNames(), hostIds, times.get(0), times.get(1));
        }
        //调用数据查询
        List<HistoryOrTrendDto> dtos = handler.handle(groupCount);
        if(CollectionUtils.isEmpty(dtos)){return historyResultList;}
        Map<String, List<HistoryOrTrendDto>> mapData = dtos.stream().collect(Collectors.groupingBy(item -> item.getItemName()));
        for (Map.Entry<String, List<HistoryOrTrendDto>> entry : mapData.entrySet()) {
            String itemName = entry.getKey();
            List<HistoryOrTrendDto> dtoList = entry.getValue();
            unitConvert(dtoList);
            //排序
            listSort(dtoList);
            MwItemHistoryResult result = new MwItemHistoryResult();
            result.setTitleName(itemName);
            MwCoordinateDataInfo dataInfo = new MwCoordinateDataInfo();
            dataInfo.setXData(dtoList.stream().map(s->s.getDate()).collect(Collectors.toList()));
            dataInfo.setYData(dtoList.stream().map(s->s.getAvgValue()).collect(Collectors.toList()));
            dataInfo.setUnit(dtoList.get(0).getUnit());
            result.setAvgData(dataInfo);
            historyResultList.add(result);
        }
        return historyResultList;
    }

    private void listSort(List<HistoryOrTrendDto> dtoList){
        Collections.sort(dtoList, new Comparator<HistoryOrTrendDto>() {
            @Override
            public int compare(HistoryOrTrendDto o1, HistoryOrTrendDto o2) {
                if(Long.parseLong(o1.getClock()) > Long.parseLong(o2.getClock())){
                    return 1;
                }
                if(Long.parseLong(o1.getClock()) < Long.parseLong(o2.getClock())){
                    return -1;
                }
                return 0;
            }
        });
    }

    private void unitConvert(List<HistoryOrTrendDto> dtoList){
        //计算平均值
        double avgValue = dtoList.stream().mapToDouble(s -> Double.parseDouble(s.getAvgValue())).average().getAsDouble();
        String unit = dtoList.get(0).getUnit();
        UnitResult result = UnitUtil.getConvertedValue(new BigDecimal(avgValue), unit);
        if(result != null){
            for (HistoryOrTrendDto dto : dtoList) {
                UnitResult unitResult = UnitUtil.getValueMap(dto.getAvgValue(), result.getUnits(), dto.getUnit());
                dto.setAvgValue(unitResult.getValue());
                dto.setUnit(unitResult.getUnits());
            }
        }
    }

}
